import { _decorator, Node, clamp, RigidBody2D, v2, v3, Vec3, Sprite, Collider2D, clamp01, tween, Tween, } from 'cc';
import { GlobalConfig } from '../../Init/Config/GlobalConfig';
import { GlobalEnum } from '../../Init/Config/GlobalEnum';
import { GlobalTmpData } from '../../Init/Config/GlobalTmpData';
import EventManager from '../../Init/Managers/EventManager';
import { EventTypes } from '../../Init/Managers/EventTypes';
import { AudioEnum } from '../../Init/SystemAudio/AudioEnum';
import { AudioSystem } from '../../Init/SystemAudio/AudioSystem';
import { StorageSystem } from '../../Init/SystemStorage/StorageSystem';
import GlobalPool from '../../Init/Tools/GlobalPool';
import { BasicEnemy } from './BasicEnemy';
const { ccclass, property } = _decorator;

@ccclass('Zombie2D')
export class Zombie2D {
    public node: Node;
    public body: RigidBody2D;
    public collider: Collider2D;
    public lineVec = v2();
    public targetPos = v3();
    public followNode: Node = null;
    //同步的属性
    public mappingProps = { node: null, state: null };

    //属性
    private moveSpd = 0;
    public moveScale = 1;
    public hp = 10;
    public maxHp = 10;
    public recoverCd = 0;
    public recoverTime = 0;
    public recoverRate = 0;

    // 保护时间
    public protectedTime = GlobalConfig.Player.protectedTime;
    public isInProtected = false;
    public curtProtectedT = 0;

    //是否隐藏
    public isHide = false;

    //是否是在游戏中同化生成
    public isCreateInLv = false;

    //#region ------------流程---------
    constructor(node: Node, followNode: Node, targePos: Vec3) {
        this.node = node;
        this.followNode = followNode;
        this.body = node.getComponent(RigidBody2D);
        this.body.enabled = true;
        this.body.linearVelocity = v2();
        //
        this.collider = node.getComponent(Collider2D);
        this.collider.sensor = false;
        this.collider.apply();
        this.targetPos.set(targePos);
        //
        this.body[GlobalEnum.ExtralProp.addLineVec] = v3();
        this.node[GlobalEnum.ExtralProp.curLineVec2d] = v2(0, 1);
        this.node[GlobalEnum.ExtralProp.customProps] = { hp: 0, maxHp: 0, isHide: this.isHide };

        this.mappingProps.node = this.node;
        this.mappingProps.state = this._curState;
        //
        this.recoverCd = GlobalConfig.Zombie.recoverCd;
        this.recoverRate = GlobalConfig.Zombie.recoverRate;
        this.recoverTime = 0;

        //
        let sp = this.node.getComponent(Sprite);
        if (sp) {
            sp.enabled = GlobalConfig.isShow2dCollider;
        }
    }

    public init(isCreateInLv = false) {
        this.isCreateInLv = isCreateInLv;
        this.setStateData();
        //角色属性
        this.getRoleProps();
    }
    //设置初始状态
    public setInitState(state = GlobalEnum.ZombieState.Idle, stateData?) {
        setTimeout(() => {
            this.changeState(state, stateData);
        }, 0);
    }

    public reset() {
        this.resetState();
        this.body.linearVelocity = v2();
        this.body.enabled = true;
        this.curtProtectedT = 0;
        this.isInProtected = false;
        this.isCreateInLv = false;
        this.moveScale = 1;
        GlobalPool.put(this.node);
    }
    public update(dt) {
        this.updateState(dt);
        this.updateCustomProp(dt);
        this.recoverHp(dt);
        this.updateProtected(dt);
    }
    private _tmpV = v3();
    public move(dt) {
        //根据当前位置与目标的位置计算速度
        this._tmpV.set(this.targetPos).add(this.followNode.position).subtract(this.node.position);
        let len = this._tmpV.length();
        //过远 强行拉回位置
        if (len > 350) {
            this.lineVec.set(0, 0);
            this.changeState(GlobalEnum.ZombieState.Idle);
            this.node.setPosition(this._tmpV.set(this.targetPos).add(this.followNode.position));
        } else {
            let extralSpdRate = (GlobalTmpData.BuffRecs[GlobalEnum.BuffType.AddSpeed] &&
                GlobalTmpData.BuffRecs[GlobalEnum.BuffType.AddSpeed].num) || 0;

            //通道加速
            if (GlobalTmpData.PartyInfo.isInPass && !GlobalTmpData.PartyInfo.isEnter) {
                extralSpdRate += clamp(GlobalConfig.Player.PassSpdRate - 1, 0, 10);
            }

            this._tmpV.normalize().multiplyScalar(this.moveSpd * (1 + extralSpdRate) * 60 * dt);
            const addVec = this.body[GlobalEnum.ExtralProp.addLineVec];
            let r = clamp(len / 15, 0.2, 2) * this.moveScale;
            this.lineVec.set(this._tmpV.x, this._tmpV.y).add(addVec).multiplyScalar(r);

            const vecLen = this.lineVec.length();

            if (addVec.x == 0 && vecLen < 3 * 60 * dt && len < 30 * 60 * dt && this._curState != GlobalEnum.ZombieState.Crawl) {
                this.lineVec.set(0, 0);
                this.changeState(GlobalEnum.ZombieState.Idle);
            } else {
                if (this.isCreateInLv && len > 20 * 60 * dt) {
                    this.changeState(GlobalEnum.ZombieState.Crawl);
                } else {
                    this.changeState(GlobalEnum.ZombieState.Run);
                }
                //记录旋转信息
                this.node[GlobalEnum.ExtralProp.curLineVec2d].set(this.lineVec);
            }
            this.body.linearVelocity = this.lineVec;
        }
    }

    //#endregion

    //#region -------------计算方法-------------------- 

    private _tmpP = v3();
    private getRoleProps() {
        let d = StorageSystem.getData();
        this.moveSpd = GlobalConfig.RolePropCfg.getMoveSpdByLv(d.userAssets.props.moveSpdLv);
        this.hp = GlobalConfig.RolePropCfg.getHpByLv(d.userAssets.props.hpLv);
        this.maxHp = this.hp;
        this.node[GlobalEnum.ExtralProp.customProps] = { hp: this.hp, maxHp: this.maxHp, isHide: this.isHide };
    }

    private _outRes = { p: v3(), r: GlobalConfig.Zombie.atkDist, outEnemy: null };
    public checkEnemy() {
        let extralDist = GlobalTmpData.BuffRecs[GlobalEnum.BuffType.AddJumpDist] && GlobalTmpData.BuffRecs[GlobalEnum.BuffType.AddJumpDist].num || 0;
        this._outRes.r = GlobalConfig.Zombie.atkDist + extralDist;
        this._outRes.outEnemy = null;
        this._outRes.p.set(this.node.position);
        EventManager.emit(EventTypes.RoleEvents.CheckEnemys, this._outRes);
        if (this._outRes.outEnemy) {
            this.changeState(GlobalEnum.ZombieState.Atk, this._outRes.outEnemy);
        }
    }
    /**atk: 攻击属性,  isHpRate 是否是百分比掉血*/
    public byAtk(atk: number, isHpRate = false) {
        if (this.hp <= 0) return;
        if (this.isInProtected) return;
        let _atk = isHpRate ? this.maxHp * atk : atk;
        this.hp -= _atk;

        if (this.hp <= 0) {
            this.hp = 0;
            this.changeState(GlobalEnum.ZombieState.Death);
            // 死亡效果
            this._tmpP.x = this.node.position.x * GlobalConfig.Scale2DTo3D;
            this._tmpP.z = -this.node.position.y * GlobalConfig.Scale2DTo3D;
            this._tmpP.y = 1;
            EventManager.emit(EventTypes.EffectEvents.show2DEffect, { t: GlobalEnum.Effect2DType.ZombieDie, p: this._tmpP });
        }
        //回复HP暂停
        this.recoverTime = 0;

        // 击中效果
        this._tmpP.x = this.node.position.x * GlobalConfig.Scale2DTo3D;
        this._tmpP.z = -this.node.position.y * GlobalConfig.Scale2DTo3D;
        this._tmpP.y = 1;
        EventManager.emit(EventTypes.EffectEvents.show2DEffect, { t: GlobalEnum.Effect2DType.ZombieHit, p: this._tmpP });

        EventManager.emit(EventTypes.RoleEvents.ShowDialog, GlobalEnum.DialogTargetType.Tips);
    }
    /**更新属性 */
    public updateCustomProp(dt) {
        this.node[GlobalEnum.ExtralProp.customProps].hp = this.hp;
        this.node[GlobalEnum.ExtralProp.customProps].maxHp = this.maxHp;
    }
    /**隐藏 */
    public setHide(isHide: boolean) {
        this.isHide = isHide;
        //显示隐藏标记
        this.node[GlobalEnum.ExtralProp.customProps].isHide = this.isHide;
    }

    // #endregion

    //#region -------------回复血量----------
    public recoverHp(dt) {
        if (this._curState == GlobalEnum.ZombieState.Win ||
            this._curState == GlobalEnum.ZombieState.Death) return;
        this.recoverTime += dt;
        if (this.recoverTime >= this.recoverCd) {
            this.recoverTime = 0;
            //
            this.hp += this.maxHp * this.recoverRate;
            this.hp = clamp(this.hp, 0, this.maxHp);
        }
    }

    public addHPByRate(r: number) {
        let addHp = this.maxHp * clamp01(r);
        this.hp = clamp(addHp + this.hp, 0, this.maxHp);
    }

    //#endregion

    //#region -------------行为状态控制-------
    public _stateRecs: { [state: number]: SubState } = {};
    public _curState: GlobalEnum.ZombieState = null;

    /**设置初始状态 */
    private setStateData() {
        this._stateRecs[GlobalEnum.ZombieState.Born] = new SubBorn(this);
        this._stateRecs[GlobalEnum.ZombieState.Idle] = new SubIdle(this);
        this._stateRecs[GlobalEnum.ZombieState.Run] = new SubRun(this);
        this._stateRecs[GlobalEnum.ZombieState.Atk] = new SubAttack(this);
        this._stateRecs[GlobalEnum.ZombieState.Win] = new SubWin(this);
        this._stateRecs[GlobalEnum.ZombieState.Death] = new SubDeath(this);
        this._stateRecs[GlobalEnum.ZombieState.Crawl] = new SubCrawl(this);
    }

    /**重置状态 */
    private resetState() {
        for (const key in this._stateRecs) {
            this._stateRecs[key].offEvents();
        }
        this._stateRecs = {};
        this._curState = null;
    }
    /**
    * 切换状态
    * @param state 
    * @param enterData 传入参数
    * @param isForth 是否强制切换
    * @returns 
    */
    public changeState(state: GlobalEnum.ZombieState, enterData?, isForth = false) {
        if (this._curState === state && !isForth) return;
        // clog.log('role:', ZombieState[state]);
        //退出之前的状态
        if (this._stateRecs[this._curState]) {
            this._stateRecs[this._curState].exit();
        }
        //切换到新的状态
        if (this._stateRecs[state]) {
            this._curState = state;
            this._stateRecs[this._curState].enter(enterData);
        }
        this.mappingProps.state = this._curState;
    }
    /**更新状态 */
    private updateState(dt) {
        if (this._stateRecs[this._curState]) {
            this._stateRecs[this._curState].update(dt);
        }
    }

    // #endregion

    //#region -------------保护时间-------
    public enterProtected(t) {
        this.isInProtected = true;
        this.curtProtectedT = 0;
        this.protectedTime = t;
        EventManager.emit(EventTypes.RoleEvents.ShowProtected, this.node.uuid, true);
    }
    protected updateProtected(dt) {
        if (this.isInProtected) {
            this.curtProtectedT += dt;
            if (this.curtProtectedT >= this.protectedTime) {
                this.isInProtected = false;
                this.exitProtected();
            }
        }
    }

    protected exitProtected() {
        EventManager.emit(EventTypes.RoleEvents.ShowProtected, this.node.uuid, false);
    }
    //#endregion 
}

//#region ---------------------僵尸 行为类型-----------------------
// subRole 行为
export class SubState {
    cmp: Zombie2D = null;

    constructor(sr: Zombie2D) {
        this.cmp = sr;
    }

    public enter(d?) {

    }
    public onEevents() {

    }
    public offEvents() {

    }
    public update(dt) {

    }
    public exit() {

    }
}
/**只有-home/引导界面 */
export class SubBorn extends SubState {
    isFinish = false;
    changeCd = 3.5;
    curt = 0;
    pos = v3();
    isGuideCrawl = false; //是否是引导关卡第一只

    public enter(d?: { isGuideCrawl: boolean }): void {
        //        
        if (!!d) {
            this.isGuideCrawl = d.isGuideCrawl;
        }

        this.curt = 0;
        this.isFinish = false;
        //位置动画
        this.posAnim();
        //
        this.bornEffect();
        // 引导对话
        if (GlobalTmpData.Game.isGuideLv) {
            setTimeout(() => {
                EventManager.emit(EventTypes.RoleEvents.EmitGuideZombieState, 0);
            }, 500);
        }

    }

    public posAnim() {
        Tween.stopAllByTarget(this.pos);
        this.pos.set(this.cmp.node.position);
        this.pos.y = -1;
        this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = this.pos.y;
        let t = this.isGuideCrawl ? this.changeCd * 0.8 : this.changeCd * 0.4;
        tween(this.pos).to(t, { y: 0 }).start();
    }
    //出生效果
    private bornEffect() {
        //前方
        let p = v3();
        p.x = this.cmp.node.position.x * GlobalConfig.Scale2DTo3D;
        p.y = 0;
        p.z = -this.cmp.node.position.y * GlobalConfig.Scale2DTo3D;
        for (let i = 0; i < 4; i++) {
            setTimeout(() => {
                EventManager.emit(EventTypes.EffectEvents.show2DEffect, { t: GlobalEnum.Effect2DType.ZombieBirth, p: p });
            }, 700 * i + 200);
        }
        //后方
        let p2 = v3(p);
        p2.y = 0.6;
        for (let i = 3; i < 6; i++) {
            setTimeout(() => {
                EventManager.emit(EventTypes.EffectEvents.show2DEffect, { t: GlobalEnum.Effect2DType.ZombieBirth, p: p2 });
            }, 600 * i);
        }

        //音效
        AudioSystem.playEffect(AudioEnum.zombieBorn);
    }

    public update(dt: any): void {
        if (this.isFinish) return;
        //计算高度
        this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = this.pos.y / GlobalConfig.Scale2DTo3D;

        this.curt += dt;
        if (this.curt >= this.changeCd) {
            this.curt = 0;
            this.bornFinished();
        }
    }

    public bornFinished() {
        this.isFinish = true;
        //切换爬行
        this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = 0;
        this.cmp.changeState(GlobalEnum.ZombieState.Crawl, { isGuideCrawl: this.isGuideCrawl });
    }

    public exit(): void {
        Tween.stopAllByTarget(this.pos);
    }
}
/**待机 */
export class SubIdle extends SubState {
    public enter(d?: any): void {
        this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = 0;
    }

    public update(dt: any): void {
        this.cmp.move(dt);
        this.cmp.checkEnemy();
    }

    public onPlaySurprise() {

    }
}
/**缓慢行走 */
export class SubCrawl extends SubState {
    scaleTime = 2;
    curt = 0;
    isGuideCrawl = false; //游戏运行时 引导关卡中第一只僵尸

    public enter(d?: { isGuideCrawl: boolean }): void {
        if (this.cmp.collider) {
            this.cmp.collider.sensor = false;
            this.cmp.collider.apply();
        }
        if (d) {
            this.isGuideCrawl = d.isGuideCrawl;
        }
        this.cmp.moveScale = 0.2;
        this.curt = 0;

        // 引导对话
        if (GlobalTmpData.Game.isGuideLv) {
            setTimeout(() => {
                EventManager.emit(EventTypes.RoleEvents.EmitGuideZombieState, 1);
            }, 800);
        }
    }
    tmpVec = v2();
    public update(dt: any): void {
        this.cmp.move(dt);
        //home界面/引导关卡初始角色 -减缓速度
        if (this.isGuideCrawl || !GlobalTmpData.Game.isGameRun) {
            this.tmpVec.set(this.cmp.lineVec).normalize().multiplyScalar(0.8);
            this.cmp.body.linearVelocity = this.tmpVec;
        }

        this.cmp.checkEnemy();
        this.updateMoveScale(dt);
    }
    private updateMoveScale(dt) {
        if (this.curt <= this.scaleTime) {
            this.curt += dt;
            this.cmp.moveScale = clamp(this.curt / this.scaleTime, 0.2, 1);
        }
    }

    public exit(): void {
        this.cmp.isCreateInLv = false;
        this.cmp.moveScale = 1;

        if (this.isGuideCrawl) {
            EventManager.emit(EventTypes.GuideEvents.ShowGuideAnim);
            GlobalTmpData.Game.isGuideFinish = true;
        }

        // 引导对话
        if (GlobalTmpData.Game.isGuideLv) {
            setTimeout(() => {
                EventManager.emit(EventTypes.RoleEvents.EmitGuideZombieState, 2);
            }, 2000)
        }
    }
}
/**行走 */
export class SubRun extends SubState {
    public enter(d?: any): void {
        if (this.cmp.collider) {
            this.cmp.collider.sensor = false;
            this.cmp.collider.apply();
        }
        this.cmp.moveScale = 1;
    }
    public update(dt: any): void {
        this.cmp.move(dt);
        this.cmp.checkEnemy();
    }
}
/**攻击 */
export class SubAttack extends SubState {
    //跳跃速度
    jumpVec = v3();
    //跳跃距离
    jumDist = 0;
    //记录已跳跃距离
    jumSumV = v3();
    //
    isJumpFinish = false;
    //
    enemy: BasicEnemy = null;

    public enter(enemy: BasicEnemy): void {
        this.enemy = enemy;
        this.jumpVec.set(enemy.node.position).subtract(this.cmp.node.position);
        this.jumDist = this.jumpVec.length();
        this.jumpVec.multiplyScalar(1 / GlobalConfig.Zombie.jumpTime);
        this.jumSumV.set(0);
        this.isJumpFinish = false;
        //
        this.enemy.aimByZombie();
        //移除碰撞效果
        this.cmp.body.linearVelocity = v2();
        this.cmp.collider.sensor = true;
        this.cmp.collider.apply();
        //计算方向
        this.cmp.node[GlobalEnum.ExtralProp.curLineVec2d].set(this.jumpVec);
        //
        EventManager.emit(EventTypes.RoleEvents.FindEnemy);

        // 引导对话
        if (GlobalTmpData.Game.isGuideLv) {
            setTimeout(() => {
                EventManager.emit(EventTypes.RoleEvents.EmitGuideZombieState, 3);
            }, 1500);
            setTimeout(() => {
                EventManager.emit(EventTypes.RoleEvents.EmitGuideZombieState, 4);
            }, 3500);
        }
        //音效
        AudioSystem.playEffect(AudioEnum.zombieJump);
    }
    public update(dt: any): void {
        this.jump(dt);
    }
    tmpV = v3();
    tmpP = v3();
    private jump(dt) {
        if (this.isJumpFinish) return;
        this.tmpV.set(this.jumpVec).multiplyScalar(dt);
        this.jumSumV.add(this.tmpV);
        const curDist = this.jumSumV.length();
        if (curDist < this.jumDist) {
            this.tmpP.set(this.cmp.node.position);
            this.tmpP.add(this.tmpV);
            //计算高度
            let h = Math.sin((curDist / this.jumDist) * 3.14) * 5;
            this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = h / GlobalConfig.Scale2DTo3D;
            this.cmp.node.setPosition(this.tmpP);

        } else {
            //跳跃结束
            this.isJumpFinish = true;
            this.cmp.node.setPosition(this.enemy.node.position);
            this.cmp.body.linearVelocity = v2();
            this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = 0;
            //检查对方是否死亡
            if (this.enemy.hp > 0) {
                switch (this.enemy.enemyType) {
                    case GlobalEnum.EnemyTypes.Army:
                        if (this.enemy.isBoss) {
                            this.enemy.byAtk(true);
                            this.cmp.changeState(GlobalEnum.ZombieState.Death);
                            // GlobalTmpData.Player.kill.boss++;
                        } else {
                            this.enemy.byAtk(true, this.back.bind(this));
                            GlobalTmpData.Player.kill[this.enemy.mappingProps.enemyName]++;
                        }
                        break;
                    case GlobalEnum.EnemyTypes.People:
                        this.enemy.byAtk(true, this.back.bind(this));
                        GlobalTmpData.Player.kill.people++;
                        break;
                    case GlobalEnum.EnemyTypes.Tank:
                        this.enemy.byAtk(false);
                        this.cmp.changeState(GlobalEnum.ZombieState.Death);
                        GlobalTmpData.Player.kill.boss++;
                        break;
                    default:
                        break;
                }
                //音效
                AudioSystem.playEffect(AudioEnum.zombieAtk);

            } else {
                //返回
                this.back();
            }
        }
    }
    //返回
    public back() {
        if (this.cmp._curState !== GlobalEnum.ZombieState.Death) {
            this.cmp.changeState(GlobalEnum.ZombieState.Run);
        }
    }

    public exit(): void {
        this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = 0;
        if (!this.isJumpFinish && this.enemy && this.enemy.hp > 0) {
            //跳跃中死亡-敌人可被攻击恢复+1
            this.enemy.aimNum++;
        }
    }
}
/**胜利 */
export class SubWin extends SubState {
    //跳跃速度
    jumpVec = v3();
    //跳跃距离
    jumDist = 0;
    //记录已跳跃距离
    jumSumV = v3();
    //
    isJumpFinish = false;
    targetPos = v3();

    public enter(d): void {
        this.cmp.body.linearVelocity = v2();
        //转2d
        this.targetPos.set(GlobalTmpData.PartyInfo.coffinPos).multiplyScalar(1 / GlobalConfig.Scale2DTo3D);
        this.targetPos.set(this.targetPos.x, -this.targetPos.z, 0);

        this.jumpVec.set(this.targetPos).subtract(this.cmp.node.position);
        this.jumDist = this.jumpVec.length();
        this.jumpVec.multiplyScalar(1 / GlobalConfig.Zombie.jumpTime);
        this.jumSumV.set(0);
        this.isJumpFinish = false;
        //
        this.cmp.body.linearVelocity = v2();
        this.cmp.collider.sensor = true;
        this.cmp.collider.apply();
        //计算方向
        this.cmp.node[GlobalEnum.ExtralProp.curLineVec2d].set(this.jumpVec);
    }

    public update(dt: any): void {
        this.jump(dt);
    }
    tmpV = v3();
    tmpP = v3();
    private jump(dt) {
        if (this.isJumpFinish) return;
        this.tmpV.set(this.jumpVec).multiplyScalar(dt);
        this.jumSumV.add(this.tmpV);
        const curDist = this.jumSumV.length();
        if (curDist < this.jumDist) {
            this.tmpP.set(this.cmp.node.position);
            this.tmpP.add(this.tmpV);
            //计算高度
            let h = Math.sin((curDist / this.jumDist) * 3.14) * 5;
            this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = h / GlobalConfig.Scale2DTo3D;
            this.cmp.node.setPosition(this.tmpP);

        } else {
            //跳跃结束
            this.isJumpFinish = true;
            this.cmp.node.setPosition(this.targetPos);
            this.cmp.body.linearVelocity = v2();
            this.cmp.node[GlobalEnum.ExtralProp.jumpHight] = 0;
            //效果
            this.tmpP.set(this.cmp.node.position.x, 0, -this.cmp.node.position.y);
            this.tmpP.multiplyScalar(GlobalConfig.Scale2DTo3D);
            EventManager.emit(EventTypes.EffectEvents.show2DEffect,
                { t: GlobalEnum.Effect2DType.ZombieBirth, p: this.tmpP });
            //金币
            let n = 2 + Math.floor(Math.random() * 2.99);
            for (let i = 0; i < n; i++) {
                EventManager.emit(EventTypes.EffectEvents.showGold3d, this.tmpP);
            }
            //
            EventManager.emit(EventTypes.RoleEvents.JumpCoverFinished, this.cmp.node.uuid);
        }
    }

}
/**失败 */
export class SubDeath extends SubState {
    public enter(d): void {
        this.cmp.body.linearVelocity = v2();
        AudioSystem.playEffect(AudioEnum.zombieDeath);
        setTimeout(() => {
            EventManager.emit(EventTypes.RoleEvents.ZombieDeath, this.cmp);
            this.cmp.node && GlobalPool.put(this.cmp.node);
        }, 1000);
    }
}
//#endregion
